import { http } from "@/utils/http";
import type { ApiResponse } from "../../user";
import { ensureArray, normalisePagination, toNumber } from "@/api/_helpers";

const REFUND_BASE = "/system/order/refund";

export interface RefundOrderParticipant {
  id: number | null;
  org_id: number | null;
  name: string;
  phone?: string;
}

export interface RefundAssistUser {
  id: number | null;
  name: string;
}

export interface RefundOrderItem {
  id: number;
  product_id: number;
  sku_id: number | null;
  quantity: number;
  unit_price: number;
  subtotal: number;
  refund_amount: number;
  product_snapshot: Record<string, any>;
}

export interface RefundOrderSummary {
  id: number;
  order_no: string;
  status: number;
  status_label: string;
  refund_status: number;
  pay_status: number;
  ship_status: number;
  source_channel: string;
  buyer_paid_amount: number;
  platform_commission_amount: number;
  buyer: RefundOrderParticipant;
  seller: RefundOrderParticipant;
  assist_user: RefundAssistUser | null;
  create_time: string;
  paid_at: string | null;
  finished_at: string | null;
  amount_snapshot: Record<string, any>;
  items: RefundOrderItem[];
}

export interface RefundRecord {
  id: number;
  refund_no: string;
  order_id: number;
  order_item_id: number | null;
  status: number;
  status_label: string;
  refund_type: string;
  reason: string;
  evidence: string[];
  apply_amount: number;
  approved_amount: number;
  buyer_amount: number;
  seller_amount: number;
  platform_amount: number;
  applicant_id: number;
  approver_id: number | null;
  remark: string;
  approve_time: string | null;
  complete_time: string | null;
  create_time: string;
  update_time: string;
  order?: RefundOrderSummary;
  item?: RefundOrderItem;
}

export interface RefundListParams {
  page?: number;
  page_size?: number;
  keyword?: string;
  status?: number | string;
  order_status?: number | string;
  order_refund_status?: number | string;
  buyer_org_id?: number | string;
  seller_org_id?: number | string;
  assist_user_id?: number | string;
  buyer_user_id?: number | string;
  seller_user_id?: number | string;
  start_time?: string;
  end_time?: string;
}

export interface RefundListResult {
  list: RefundRecord[];
  pagination: {
    total: number;
    pageSize: number;
    currentPage: number;
  };
  raw: Record<string, any>;
}

const mapParticipant = (
  payload: Record<string, any> | undefined,
  fallbackId: unknown,
  fallbackOrgId: unknown
): RefundOrderParticipant => {
  return {
    id:
      fallbackId !== undefined && fallbackId !== null
        ? toNumber(fallbackId, 0)
        : payload?.id !== undefined
          ? toNumber(payload.id, 0)
          : null,
    org_id:
      fallbackOrgId !== undefined && fallbackOrgId !== null
        ? toNumber(fallbackOrgId, 0)
        : payload?.org_id !== undefined
          ? toNumber(payload.org_id, 0)
          : null,
    name: payload?.name ?? "",
    phone: payload?.phone ?? ""
  };
};

const mapOrderItem = (item: Record<string, any>): RefundOrderItem => ({
  id: toNumber(item.id, 0),
  product_id: toNumber(item.product_id, 0),
  sku_id:
    item.sku_id !== undefined && item.sku_id !== null
      ? toNumber(item.sku_id, null)
      : null,
  quantity: toNumber(item.quantity, 0),
  unit_price: Number(item.unit_price ?? 0),
  subtotal: Number(item.subtotal ?? item.subtotal_amount ?? 0),
  refund_amount: Number(item.refund_amount ?? 0),
  product_snapshot: (item.product_snapshot as Record<string, any>) ?? {}
});

const mapOrderSummary = (payload: Record<string, any>): RefundOrderSummary => {
  const buyerPayload = (payload.buyer ?? {}) as Record<string, any>;
  const sellerPayload = (payload.seller ?? {}) as Record<string, any>;
  const assistPayload = (payload.assist_user ?? {}) as Record<string, any>;

  return {
    id: toNumber(payload.id, 0),
    order_no: payload.order_no ?? "",
    status: toNumber(payload.status, 0),
    status_label: payload.status_label ?? "",
    refund_status: toNumber(payload.refund_status, 0),
    pay_status: toNumber(payload.pay_status, 0),
    ship_status: toNumber(payload.ship_status, 0),
    source_channel: payload.source_channel ?? "",
    buyer_paid_amount: Number(payload.buyer_paid_amount ?? 0),
    platform_commission_amount: Number(payload.platform_commission_amount ?? 0),
    buyer: mapParticipant(
      buyerPayload,
      payload.buyer?.id ?? payload.buyer_user_id,
      payload.buyer?.org_id ?? payload.buyer_org_id
    ),
    seller: mapParticipant(
      sellerPayload,
      payload.seller?.id ?? payload.seller_user_id,
      payload.seller?.org_id ?? payload.seller_org_id
    ),
    assist_user:
      assistPayload && Object.keys(assistPayload).length > 0
        ? {
            id:
              assistPayload.id !== undefined && assistPayload.id !== null
                ? toNumber(assistPayload.id, 0)
                : payload.assist_user_id !== undefined &&
                    payload.assist_user_id !== null
                  ? toNumber(payload.assist_user_id, 0)
                  : null,
            name: assistPayload.name ?? ""
          }
        : payload.assist_user_id
          ? {
              id: toNumber(payload.assist_user_id, 0),
              name: ""
            }
          : null,
    create_time: payload.create_time ?? "",
    paid_at: payload.paid_at ?? null,
    finished_at: payload.finished_at ?? null,
    amount_snapshot: (payload.amount_snapshot as Record<string, any>) ?? {},
    items: ensureArray<Record<string, any>>(payload.items ?? []).map(
      mapOrderItem
    )
  };
};

const mapRefundRecord = (payload: Record<string, any>): RefundRecord => ({
  id: toNumber(payload.id, 0),
  refund_no: payload.refund_no ?? "",
  order_id: toNumber(payload.order_id, 0),
  order_item_id:
    payload.order_item_id !== undefined && payload.order_item_id !== null
      ? toNumber(payload.order_item_id, 0)
      : null,
  status: toNumber(payload.status, 0),
  status_label: payload.status_label ?? "",
  refund_type: payload.refund_type ?? "",
  reason: payload.reason ?? "",
  evidence: ensureArray<string>(payload.evidence ?? []).filter(Boolean),
  apply_amount: Number(payload.apply_amount ?? 0),
  approved_amount: Number(payload.approved_amount ?? 0),
  buyer_amount: Number(payload.buyer_amount ?? 0),
  seller_amount: Number(payload.seller_amount ?? 0),
  platform_amount: Number(payload.platform_amount ?? 0),
  applicant_id: toNumber(payload.applicant_id ?? payload.buyer_id, 0),
  approver_id:
    payload.approver_id !== undefined && payload.approver_id !== null
      ? toNumber(payload.approver_id, 0)
      : null,
  remark: payload.remark ?? "",
  approve_time: payload.approve_time ?? null,
  complete_time: payload.complete_time ?? null,
  create_time: payload.create_time ?? "",
  update_time: payload.update_time ?? "",
  order: payload.order ? mapOrderSummary(payload.order) : undefined,
  item: payload.item ? mapOrderItem(payload.item) : undefined
});

const sanitiseParams = (params: RefundListParams) => {
  const result: Record<string, any> = {};
  Object.entries(params).forEach(([key, value]) => {
    if (value === undefined || value === null || value === "") return;
    result[key] = value;
  });
  return result;
};

const fetchList = async (
  params: RefundListParams = {}
): Promise<RefundListResult> => {
  const page = toNumber(params.page, 1);
  const pageSize = toNumber(params.page_size, 10);

  const res = await http.request<ApiResponse<any>>("get", REFUND_BASE, {
    params: sanitiseParams({
      ...params,
      page,
      page_size: pageSize
    })
  });

  const payload = (res?.data as Record<string, any>) ?? {};
  const listSource =
    payload.list ?? payload.data ?? payload.records ?? payload.items ?? [];

  const list =
    ensureArray<Record<string, any>>(listSource).map(mapRefundRecord);

  const pagination = normalisePagination(
    payload.pagination ?? payload,
    page,
    pageSize,
    list.length
  );

  return {
    list,
    pagination,
    raw: payload
  };
};

const fetchDetail = async (id: number | string): Promise<RefundRecord> => {
  const res = await http.request<ApiResponse<any>>(
    "get",
    `${REFUND_BASE}/${id}`
  );
  const payload = (res?.data as Record<string, any>) ?? {};
  if (payload?.id !== undefined) {
    return mapRefundRecord(payload);
  }
  return mapRefundRecord(payload ?? {});
};

export default {
  fetchList,
  fetchDetail
};
